#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "filesystem/fs.h"
#include "message/message.h"
#include "util/util.h"
#include "superblock/Superblock.h"

//vars
char * commandline;
char * templine;
char * command;
char * arg0;
char * arg1;
char * token;
pid_t  pid_fs;
char isMounted = 0;
char isEverMounted = 0;
FILE * harddisk;

int main(){
	//command & args vars declaration
	commandline = (char*) malloc (300);
	templine = (char*) malloc (300);
	command = (char*) malloc (100);
	arg0 = (char*) malloc (100);
	arg1 = (char*) malloc (100);
	
	//main loop
	do{
		//reinitialization command & args
		strcpy(command,"");
		strcpy(arg0,"");
		strcpy(arg1,"");
		
		//get user input
		printf("> ");
		gets(commandline);
		strcpy(templine,commandline);
		
		//tokenize user input
		token = strtok(commandline, " ");
		int i = 0;
		while (token) {
			switch (i){
				case 0: strcpy(command,token); break;
				case 1: strcpy(arg0,token); break;
				case 2: strcpy(arg1,token); break;
			}
			token = strtok(NULL, " ");
			i++;
		}
		
		if(strcmp(command,"format")==0){			
			FILE * hdd;
			//format @[filepath] [size]
			//hilangkan @ dari filepath
			char * path = ilanginAt(arg0);
			//buat file baru untuk jadi device harddisk
			hdd = fopen(path,"w");
			//diinisiasi agar ukurannya sesuai dengan input user
			unsigned long i, size = strtoul(arg1,NULL,0);
			for(i=0;i<size;i++){
				fputc(0,hdd);
			}
			//inisiasi superblock
			writeName(hdd,"56fs");
			writeSize(hdd,size);
			writeStatus(hdd,1);
			//berikan user feedback
			printf("New disk has been formatted at %s\n",path);			
			//ilangin file descriptor dari memori
			fclose(hdd);
		} else if(strcmp(command,"mountfs")==0 && !isMounted){			
			//mountfs @[filepath] [mount_point]
			isEverMounted = 1;
			//hilangkan @ dari filepath
			char * path = ilanginAt(arg0);
			//bikin anak pakai fork
			pid_fs = fork();
			if(pid_fs==0){
				//buat file baru untuk jadi device harddisk
				harddisk = fopen(path,"r+");
				//berhasil anakan, jebak anak di loop tiada henti start_fs()
				start_fs(harddisk);
				//kalo udah keluar dari main loop filesystem, matiin proses child dengan ngexit
				printf("cobain\n");
				exit(0);
			} else {
				//bapaknya ke sini, ngirim info mount file path ke anak
				sendMessage(templine);
				isMounted = 1;
			}
		} else if(strcmp(command,"umount")==0){
			//bunuh child agar tidak jadi zombie			
			sendMessage("exit");
			//menunggu child mati
			int stat_val;
			pid_t child_pid;
			printf("Unmounting filesystem...\n");			
			child_pid = wait(&stat_val);
			//bila child sudah mati, langsung kasi user feedback
			printf("Filesystem has unmounted: PID = %d\n", child_pid);
			isMounted = 0;
		} else if(strcmp(command, "exit")==0){
			//do nothing
		} else {
			//untuk command selain mountfs dan format, langsung kirim ke filesystem ajah
			printf("send message command line = %s\n", templine);
			sendMessage(templine);
			//printf("This line is from pid %d\n", getpid());
		}	
	} while (strcmp(command,"exit")!=0); //repeat until exit command detected
		
	if(isEverMounted){
		int stat_val;
		pid_t child_pid;
		printf("Unmounting filesystem...\n");
		//menunggu child
		child_pid = wait(&stat_val);
		//ilangin file descriptor dari memori
		fclose(harddisk);
		printf("Filesystem has unmounted: PID = %d\n", child_pid);
	}
	printf("Program exiting...\n");
	
	return 0;
}

